<template>
  <el-dialog
    v-el-drag-dialog="{heightAuto: true, updataFull, updataDialogWidth}"
    :fullscreen="isfullscreen"
    :title="$t('AUTH_TYPE_FUNC')"
    :visible="visible"
    :width="setDialogWidth('550px')"
    @open="open"
    @close="close"
  >
    <el-form label-width="auto" style="height:400px;">
      <el-form-item :label="$t('AUTH_MODE')" class="hide">
        <el-radio-group v-model="auth.authMode" size="medium" @change="radio_change">
          <el-radio-button label="NONE">{{ $t('WITHOUT') }}</el-radio-button>
          <el-radio-button label="IN">{{ $t('CONTAIN') }}</el-radio-button>
          <el-radio-button label="EXC">{{ $t('EXCLUDE') }}</el-radio-button>
          <el-radio-button label="ALL">{{ $t('ALL') }}</el-radio-button>
        </el-radio-group>
      </el-form-item>
      <el-form-item v-show="isBind" :label="$t('FUCNTION_LIST')">
        <el-tree ref="tree" :key="renderKey" node-key="funcId" :data="treeData" show-checkbox />
      </el-form-item>
    </el-form>
    <template v-slot:footer>
      <el-button @click="close">{{ $t('CANCEL') }}</el-button>
      <el-button type="primary" @click="save">{{ $t('SAVE') }}</el-button>
    </template>
  </el-dialog>
</template>

<script>
  import { mapGetters } from 'vuex'
  import { difference, uniq } from 'lodash'
  import { buildTree, getParentsById } from '@/utils/common'
  import FuncApi from '@/api/system/FuncApi'
  import AuthApi from '@/api/system/AuthApi'
  import OperateLogApi from '@/api/system/OperateLogApi.js'
  export default {
    props: {
      visible: Boolean,
      data: {
        type: Object,
        default: () => {}
      }
    },
    data() {
      return {
        renderKey: 0,
        treeData: [],
        treeProps: {
          label: 'funcName',
          children: 'children'
        },
        auth: {
          authType: 'FUNC',
          relateType: 'ROLE_FUNC',
          authMode: 'NONE',
          targetList: []
        },
        allLastNode: [], // 最后一级根节点
        checks: [], // 后端返回的所有的最后一级根节点
        originAuthMode: '', // 后端返回的权限模式
        originFuncList: []
      }
    },
    computed: {
      isBind() {
        return this.auth.authMode !== 'NONE' && this.auth.authMode !== 'ALL'
      },
      ...mapGetters(['getRoles', 'getUserId', 'getUser'])
    },
    created() {
      // 功能树列表
      if (this.getRoles[0] === 'admin') {
        FuncApi.tree().then(result => {
          if (!result || !result.length) {
            return
          }
          this.treeData = result
          this.loopFun_tree(result, this.allLastNode)
        })
      }
      if (this.getRoles[0] === 'admin') return
      // 拍平后的功能列表
      FuncApi.list().then(result => {
        if (!result || !result.length) {
          return
        }
        this.originFuncList = result
        // 根据当前登录用户的角色，获取角色对应的功能列表
        AuthApi.getAuth(this.getRoles[0], 'ROLE_FUNC').then(result => {
          if (!result.targetList || !result.targetList.length) {
            return
          }
          const filterFuncList = this.originFuncList.filter(i =>
            result.targetList.includes(i.funcId)
          )
          this.treeData = buildTree(filterFuncList, 'funcId', 'parentId', 'children') // 返回当前登录用户能操作的功能树
          this.loopFun_tree(this.treeData, this.allLastNode)
        })
      })
    },
    methods: {
      open() {
        this.renderKey += 1
        this.auth.objectId = this.data.roleId
        this.auth.objectName = this.data.roleName
        this.auth.authMode = 'NONE'
        this.auth.targetList = []
        this.$refs.tree && this.$refs.tree.setCheckedKeys([])
        this.checks = []
        this.originAuthMode = 'NONE'
        AuthApi.getAuth(this.data.roleId, 'ROLE_FUNC').then(result => {
          this.$nextTick(() => {
            this.auth.authMode = 'IN'
            this.radio_change()
          })
          if (!result) {
            return
          }
          this.auth.authMode = result.authMode
          this.originAuthMode = result.authMode
          if (!result.targetList || !result.targetList.length) {
            return
          }
          this.auth.targetList = result.targetList
          this.checks = result.targetList.filter(
            funcId =>
              this.$refs.tree.getNode(funcId) &&
              this.$refs.tree.getNode(funcId).childNodes.length === 0
          )
          this.$refs.tree.setCheckedKeys(this.checks)
        })
      },
      save() {
        if (this.isBind) {
          this.auth.targetList = [
            ...this.$refs.tree.getHalfCheckedKeys(),
            ...this.$refs.tree.getCheckedKeys()
          ]
        } else {
          this.auth.targetList = []
        }
        AuthApi.authorize(this.auth)
          .then(result => {
            this.$message.success(this.$t('OPERATE_SUCCESS'))
            this.addLog(true)
            this.close()
          })
          .catch(err => {
            console.log(err)
            this.addLog(false)
          })
      },
      close() {
        this.$emit('close')
      },
      // 筛选出所有的根节点
      loopFun_tree(list, arr) {
        list.forEach(e => {
          if (e.children && e.children.length) {
            this.loopFun_tree(e.children, arr)
          } else {
            arr.push(e.funcId)
          }
        })
      },
      radio_change() {
        this.$refs.tree.setCheckedKeys([])
        if (this.auth.authMode === 'IN') {
          if (this.originAuthMode === 'IN') {
            this.$refs.tree.setCheckedKeys(this.checks)
          } else if (this.originAuthMode === 'EXC') {
            this.$refs.tree.setCheckedKeys(difference(this.allLastNode, this.checks))
          }
        } else if (this.auth.authMode === 'EXC') {
          if (this.originAuthMode === 'IN') {
            this.$refs.tree.setCheckedKeys(difference(this.allLastNode, this.checks))
          } else if (this.originAuthMode === 'EXC') {
            this.$refs.tree.setCheckedKeys(this.checks)
          }
        }
      },
      addLog(result = true) {
        // 对比前后变化
        const newChecks = this.$refs.tree.getCheckedKeys().filter(
          funcId =>
            this.$refs.tree.getNode(funcId) &&
            this.$refs.tree.getNode(funcId).childNodes.length === 0
        )
        const diffChecks = uniq(difference(newChecks, this.checks).concat(difference(this.checks, newChecks)))
        // 判断两个两个数组差项是新增还是减少
        const addChecks = [] // 存增加的
        const reduceChecks = [] // 存减少的
        diffChecks.forEach(i => {
          if (this.checks.includes(i)) {
            reduceChecks.push(i)
          }
          if (newChecks.includes(i)) {
            addChecks.push(i)
          }
        })
        // 取消了哪些
        let reduceChecksStr = ''
        reduceChecks.forEach(i => {
          const parentList = (getParentsById(this.treeData, i, 'funcId') || [])
          if (parentList.length) {
            const parentListStr = parentList.reverse().reduce((prev, cur, index, arr) => {
              if (arr.length - 1 === index) {
                return prev + cur.label
              } else {
                return prev + cur.label + '-'
              }
            }, '')
            reduceChecksStr += this.$t('FUNC_CANCEL_LOG', { funcName: parentListStr })
          }
        })
        // 选中了哪些
        let addChecksStr = ''
        addChecks.forEach(i => {
          const parentList = (getParentsById(this.treeData, i, 'funcId') || [])
          if (parentList.length) {
            const parentListStr = parentList.reverse().reduce((prev, cur, index, arr) => {
              if (arr.length - 1 === index) {
                return prev + cur.label
              } else {
                return prev + cur.label + '-'
              }
            }, '')
            addChecksStr += this.$t('FUNC_SELECTED_LOG', { funcName: parentListStr })
          }
        })
        const content = {
          roleName: this.data.roleName,
          roleId: this.data.roleId,
          currentUserId: this.getUserId,
          reduceChecksStr: reduceChecksStr,
          addChecksStr: addChecksStr,
          i18nKey: 'AUTH_TYPE_FUNC_LOG' // 功能权限日志
        }
        // console.log(reduceChecksStr, addChecksStr)
        // 记录登录日志
        try {
          diffChecks.length && OperateLogApi.addLog({
            api: '/auth/authorize',
            item: 'MENU_ROLE_MANAGER', // 角色管理
            terminal: 'AUTH_TYPE_FUNC', // 功能权限
            object: this.data.roleName,
            operateResult: result,
            realName: this.getUser.realName,
            content: JSON.stringify(content)
          })
        } catch (error) {

        }
      }
    }
  }
</script>

<style scoped></style>
